/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package procesosDiscretos;

import ec.util.MersenneTwisterFast;
import generadorva.Exponencial;
import java.text.DecimalFormat;

/**
 *
 * @author USUARIO
 */
public class SimulacionCola {
    
    public static void main(String[] args) {
        MersenneTwisterFast prng = new MersenneTwisterFast(1324567);
        double lambda = 1d/5d;
        Exponencial tiempoLLegada = new Exponencial(lambda);
        System.out.println("Media esperada de tiempo de llegada: " + (1d/tiempoLLegada.getLambda()) + " minutos");
        lambda = 1d/4.5d;
        Exponencial tiempoServicio = new Exponencial(lambda);
        System.out.println("Media esperada de tiempo de servicio: " + (1d/tiempoServicio.getLambda()) + " minutos");
        lambda = 1d/3d;
        Exponencial impaciencia = new Exponencial(lambda);
        System.out.println("Media esperada de tiempo de impaciencia: " + (1d/impaciencia.getLambda()) + " minutos");
        double SumaLQ;
        double SumaWn;
        double Wn;
        double TSn;
        double TSn_1;
        double TLn;
        double TLn_1;
        double Sn;
        double impaciencia_i; // impaciencia del clinte i
        double Tn = impaciencia_i = Sn = TLn_1 = TLn = TSn_1 = TSn = Wn = SumaWn = SumaLQ = 0;
        int numClientes = 10000;
        int numClientesImpacientes = 0;
        double promedioExponencial = 0d;
        DecimalFormat decimalFormat = new DecimalFormat("##.######");
        for (int i = 0; i < numClientes; i++) {
            Tn = tiempoLLegada.generate(prng.nextDouble());
            Sn = tiempoServicio.generate(prng.nextDouble());
            impaciencia_i = impaciencia.generate(prng.nextDouble());
            promedioExponencial += Tn;
            //System.out.println("Tn: " + decimalFormat.format(Tn) + " Sn: " + decimalFormat.format(Sn) + " imp: " + decimalFormat.format(impaciencia_i) );
            TLn = TLn_1 + Tn;
            if (TLn > TSn_1) {
                TSn = TLn + Sn;
                Wn = 0;
            } else {
                Wn = TSn_1 - TLn;
                if (Wn > impaciencia_i) {
                    numClientesImpacientes++;
                    Wn = impaciencia_i; // si la impaciencia es menor que la espera, el cliente se va
                    TSn = TSn_1; // por lo tanto no es atendido y el reloj de servicio permanece igual
                } else{
                    TSn = TSn_1 + Sn; // si el cliente es paciente, es atendido y el reloj de servicio aumenta
                }
            }
            SumaWn += Wn;
            TLn_1 = TLn;
            TSn_1 = TSn;
        }
        double WPromedio = SumaWn / numClientes;
        promedioExponencial = promedioExponencial / numClientes;
        System.out.println("Numero total de clientes: " + numClientes);
        System.out.println("Promedio real de tiempo de llegada: " + decimalFormat.format(promedioExponencial) + " minutos");
        System.out.println("espera promedio por cliente: " + decimalFormat.format(WPromedio) + " minutos");
        System.err.println("Clientes impacientes: "+ numClientesImpacientes);
    }
    
}
